package com.xiang.ad.index.adunit;

import com.xiang.ad.index.IndexAware;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by xiang.
 * 推广单元index的crud
 */
@Slf4j
@Component
public class AdUnitIndex implements IndexAware<Long, AdUnitObject> {

    //使用map存储 index
    private static Map<Long, AdUnitObject> objectMap;

    //考虑线程安全，使用ConcurrentHashMap 初始化map
    static {
        objectMap = new ConcurrentHashMap<>();
    }

    //根据开屏还是贴片、、、进行匹配
    public Set<Long> match(Integer positionType) {

        Set<Long> adUnitIds = new HashSet<>();

        objectMap.forEach((k, v) -> {
            //根据流量类型，进行检验和匹配判断
            if (AdUnitObject.isAdSlotTypeOK(positionType,
                    v.getPositionType())) {
                adUnitIds.add(k);
            }
        });

        return adUnitIds;
    }

    //根据上面匹配获取到的adUnitIds，获取对应的索引对象
    public List<AdUnitObject> fetch(Collection<Long> adUnitIds) {

        //非空校验
        if (CollectionUtils.isEmpty(adUnitIds)) {
            return Collections.emptyList();
        }

        //存放AdUnitObject索引对象
        List<AdUnitObject> result = new ArrayList<>();

        //遍历 根据adUnitIds进行获取对应的索引对象
        adUnitIds.forEach(u -> {
            AdUnitObject object = get(u);
            if (object == null) {
                log.error("AdUnitObject not found: {}", u);
                return;
            }
            result.add(object);
        });

        //
        return result;
    }

    // 获取
    @Override
    public AdUnitObject get(Long key) {
        return objectMap.get(key);
    }

    //添加索引 key是    value是AdUnitObject
    @Override
    public void add(Long key, AdUnitObject value) {

        log.info("before add: {}", objectMap);
        objectMap.put(key, value);
        log.info("after add: {}", objectMap);
    }

    // 更新索引
    @Override
    public void update(Long key, AdUnitObject value) {

        log.info("before update: {}", objectMap);

        AdUnitObject oldObject = objectMap.get(key);
        if (null == oldObject) {//为空 就put创建索引
            objectMap.put(key, value);
        } else {//非空，则更新
            oldObject.update(value);
        }

        log.info("after update: {}", objectMap);
    }

    //删除索引
    @Override
    public void delete(Long key, AdUnitObject value) {

        log.info("before delete: {}", objectMap);
        objectMap.remove(key);//删除
        log.info("after delete: {}", objectMap);
    }
}
